/*
 *   本文件属于Raiiwhen的个人库代码仓
 *   cioMst.cpp & .h 用于cio的上位机工具类
 *
 *   THIS PROGRAM IS FREE SOFTWARE WITH NO LIMIT, IS LICENSED UNDER BALABALA.LIC,
 *   USE IT AS YOU WANT, AND BUY A COLA WHEN MET AUTHOR
 *
 *   Copyright (c) 2023 Raiiwhen masterraii@icloud.com
 */

#ifndef CIOMST_H
#define CIOMST_H

#include <cstdint>
#include <vector>
#include <queue>
#include <string>
#include <mutex>
#include "../common_typedef.h"
#include "../frm_struct_def.h"
#include "MstStatistics.h"

constexpr size_t BUFFER_MAX_SIZE = 1024 * 10; // 10KB rxBuffer

struct MstCioObj
{
    pkgType type { INVALID };
    std::vector<uint8_t> data;
    MstCioObj() {}
    MstCioObj(pkgType tp) : type(tp) {}
    MstCioObj(pkgType tp, const void* src, size_t len)
    {
        type = tp;
        const uint8_t* pSrc = reinterpret_cast<const uint8_t*>(src);
        data.assign(pSrc, pSrc + len);
    }
};


class cioMst
{
public:
    cioMst(std::string pkgHead) : m_pkgHead(pkgHead)
    {
        m_stat = std::make_shared<MstStatistics>(BUFFER_MAX_SIZE);
    }
    virtual ~cioMst() {}
    /* recv bytes from PhyChannel and update external task queue */
    void RxData(const std::vector<uint8_t>& newData, std::queue<MstCioObj>& extQueue);
    void TxPkg(std::vector<uint8_t>& dst, pkgType type, const void* data = nullptr, size_t len = 4);
    /* CioMst State Monitor */
    void SetBytesAvailable(size_t cnt) { m_stat->bytesAvailable = cnt; }
    MstStatisticsHandle GetStatic();

private:
    std::string m_pkgHead;
    std::vector<uint8_t> m_rxBuffer; // recvBuffer
    MstStatisticsHandle m_stat { nullptr };

    MstCioObj Decode(const uint8_t* data, size_t dataLen) const;
    size_t DecodePkgLen(const uint8_t* data, size_t dataLen) const;
    FrmTransState CheckOutRx(const uint8_t* data, size_t dataLen) const;
};

#endif // CIOMST_H
